package maple.thelittleredbook.user.controller;

import jakarta.validation.Valid;

import lombok.extern.slf4j.Slf4j;
import maple.thelittleredbook.common.exception.ForbiddenException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import maple.thelittleredbook.common.dto.ApiResponse;
import maple.thelittleredbook.common.service.AuthService;
import maple.thelittleredbook.logging.annotation.SystemLog;
import maple.thelittleredbook.user.dto.*;
import maple.thelittleredbook.user.service.UserService;
import maple.thelittleredbook.user.service.VerificationService;

@Slf4j
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    private final VerificationService verificationService;
    private final UserService userService;
    private final AuthService authService;

    @Autowired
    public AuthController(VerificationService verificationService,
                          UserService userService,
                          AuthService authService) {
        this.verificationService = verificationService;
        this.userService = userService;
        this.authService = authService;
    }

    /**
     * 发送验证码
     */
    @PostMapping("/send-verification-code")
    @SystemLog(operation = "发送验证码")
    public ResponseEntity<ApiResponse<String>> sendVerificationCode(
            @Valid @RequestBody EmailVerificationRequestDTO requestDTO) {

        boolean sent = verificationService.createAndSendVerificationCode(
                requestDTO.getEmail(),
                requestDTO.getPurpose()
        );

        if (sent) {
            return ResponseEntity.ok(ApiResponse.success("验证码已发送至您的邮箱"));
        } else {
            return ResponseEntity.ok(ApiResponse.fail("验证码发送失败，请稍后重试"));
        }
    }

    /**
     * 普通用户注册
     */
    @PostMapping("/register")
    @SystemLog(operation = "用户注册")
    public ResponseEntity<ApiResponse<UserDTO>> registerUser(
            @Valid @RequestBody UserRegistrationDTO requestDTO) {

        UserDTO userDTO = userService.registerUser(requestDTO);
        return ResponseEntity.ok(ApiResponse.success("注册成功", userDTO));
    }


    /**
     * 管理员注册（需要超级管理员审核）
     */
    @PostMapping("/register-admin")
    @SystemLog(operation = "管理员注册")
    public ResponseEntity<ApiResponse<UserDTO>> registerAdmin(
            @Valid @RequestBody UserRegistrationDTO requestDTO) {

        UserDTO userDTO = userService.registerAdmin(requestDTO);
        return ResponseEntity.ok(ApiResponse.success("管理员注册成功，申请邮件已发送至超级管理员，请等待审核", userDTO));

    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    @SystemLog(operation = "用户登录")
    public ResponseEntity<ApiResponse<LoginResponseDTO>> login(
            @Valid @RequestBody LoginRequestDTO requestDTO) {

        LoginResponseDTO responseDTO = userService.login(requestDTO);
        return ResponseEntity.ok(ApiResponse.success("登录成功", responseDTO));
    }

    /**
     * 刷新JWT Token
     * 直接从Spring Security上下文获取用户信息
     */
    @PostMapping("/refresh-token")
    @SystemLog(operation = "刷新Token", saveResponseData = false)
    public ResponseEntity<ApiResponse<LoginResponseDTO>> refreshToken() {

        Long userId = authService.getCurrentUserId();
        if (userId == null) {
            return ResponseEntity.ok(ApiResponse.fail("用户未登录或登录已过期"));
        }

        LoginResponseDTO responseDTO = userService.refreshTokenByUserId(userId);
        return ResponseEntity.ok(ApiResponse.success("Token刷新成功", responseDTO));
    }

    /**
     * 通过验证码重置密码
     */
    @PostMapping("/reset-password")
    @SystemLog(operation = "重置密码")
    public ResponseEntity<ApiResponse<String>> resetPassword(
            @Valid @RequestBody PasswordResetRequestDTO requestDTO) {

        boolean success = userService.resetPasswordByCode(
                requestDTO.getEmail(),
                requestDTO.getVerificationCode(),
                requestDTO.getNewPassword()
        );

        if (success) {
            return ResponseEntity.ok(ApiResponse.success("密码重置成功"));
        } else {
            return ResponseEntity.ok(ApiResponse.fail("密码重置失败"));
        }
    }

    /**
     * 修改密码（需要旧密码验证）
     * 直接从Spring Security上下文获取用户ID
     */
    @PostMapping("/change-password")
    @SystemLog(operation = "修改密码")
    public ResponseEntity<ApiResponse<String>> changePassword(
            @Valid @RequestBody ChangePasswordRequestDTO requestDTO) {

        Long userId = authService.getCurrentUserId();
        if (userId == null) {
            return ResponseEntity.ok(ApiResponse.fail("用户未登录或登录已过期"));
        }

        boolean success = userService.changePassword(
                userId,
                requestDTO.getOldPassword(),
                requestDTO.getNewPassword()
        );

        if (success) {
            return ResponseEntity.ok(ApiResponse.success("密码修改成功"));
        } else {
            return ResponseEntity.ok(ApiResponse.fail("密码修改失败"));
        }
    }

    /**
     * 审核管理员申请
     */
    @PostMapping("/admin/applications/{userId}/review")
    @SystemLog(operation = "审核管理员申请")
    public ResponseEntity<ApiResponse<String>> reviewAdminApplication(
            @PathVariable Long userId,
            @Valid @RequestBody AdminReviewRequestDTO requestDTO) {

        // 检查当前用户是否为超级管理员
        if (!authService.isCurrentUserSUPERADMIN()) {
            throw new ForbiddenException("只有超级管理员可以审核管理员申请");
        }

        // 获取当前用户ID，让Service层去处理用户信息获取
        Long currentUserId = authService.getCurrentUserId();
        if (currentUserId == null) {
            throw new IllegalArgumentException("审核人信息异常");
        }

        boolean success = userService.reviewAdminApplication(
                userId,
                requestDTO.getApproved(),
                currentUserId,  // 传递审核人ID，让Service层处理
                requestDTO.getRejectReason()
        );

        if (success) {
            String message = requestDTO.getApproved() ? "管理员申请审核通过" : "管理员申请已拒绝";
            return ResponseEntity.ok(ApiResponse.success(message));
        } else {
            throw new RuntimeException("审核操作失败");
        }
    }
}